package com.bridge.down.image;

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class PicSpider {

    public static void main(String[] args) throws Exception {
        PicSpider spider = new PicSpider();
        List<String> urls =  spider.crawlePicture( "美女", 5);
        spider.download(urls);
    }

    public List<String> crawlePicture(String queryWord, int page) throws Exception {
        if (page < 1) {
            throw new Exception("page set error.");
        }
        PageUrl pageUrl = new PageUrl(queryWord, 30);
        List<String> list = new ArrayList<>();
        for (int i = 1; i <= page; i++) {
            pageUrl.setPn(i * 30);
            list.addAll(resolveJson( getJson(pageUrl.toString())));
        }
        return  list;
    }


    public String getJson(String url) {
        String json = null;
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet getMethod = new HttpGet(url);
            setHeaders(getMethod);
            try (CloseableHttpResponse response = httpClient.execute(getMethod)) {
                int statusCode = response.getStatusLine().getStatusCode();
                if (statusCode == HttpStatus.SC_OK) {
                    HttpEntity entity = response.getEntity();
                    if (entity != null) {
                        json = EntityUtils.toString(entity, "UTF-8");
                        resolveJson(json);
                    }
                } else {
                    throw new IOException("请求失败：" + statusCode);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return json;
    }

    public List<String> resolveJson(String json) {
        // 使用正则表达式，进行匹配，获取 objURL
        String regx = "\"thumbURL\":\"(.*?)\",";
        Pattern p = Pattern.compile(regx);
        Matcher m = p.matcher(json);
        List<String> strs = new LinkedList<>();
        while (m.find()) {
            strs.add(m.group(0));
        }
        // 使用 Stream API 进行处理并返回。
        return strs.stream().map(s -> s.substring(12, s.length() - 2)).collect(Collectors.toList());
    }
    public void download(List<String> urlList) {
        // 用于统计一些数据
        AtomicInteger successCount = new AtomicInteger(0), failCount = new AtomicInteger(0),
                exceptionCount = new AtomicInteger(0);
        // 设置超时时间
        RequestConfig config = RequestConfig.custom().setSocketTimeout(10 * 1000).setConnectTimeout(10 * 1000)
                .setConnectionRequestTimeout(10 * 1000).setRedirectsEnabled(false) // 不允许自动重定向，否则会把html页面当成图片下载下来
                .build();
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            urlList.forEach(url -> {
                HttpGet getMethod = new HttpGet(url);
                try (CloseableHttpResponse response = httpClient.execute(getMethod)) {
                    int statusCode = response.getStatusLine().getStatusCode();
                    if (statusCode == HttpStatus.SC_OK) {
                        HttpEntity entity = response.getEntity();
                        if (entity != null) {
                            String filename = this.getFileName(url);
                            File file = new File("C:\\Users\\Administrator\\Pictures\\" + filename);
                            if (!file.exists()) {
                                file.getParentFile().mkdirs();
                            }
                            try (OutputStream out = new BufferedOutputStream(new FileOutputStream(file))) {
                                entity.writeTo(out);
                                successCount.getAndIncrement();
                                System.out.println(statusCode + " success: " + url + "\n" + filename);
                            }
                        }
                    } else {
                        failCount.getAndIncrement();
                        System.out.println(statusCode + " fail: " + url);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    exceptionCount.getAndIncrement();
                    System.out.println("IOException: " + url);
                }
            });
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        System.out.println("statistic data[ " + "Success: " + successCount.get() + "\n" + "Fail: " + failCount.get()
                + "\n" + "Exception: " + exceptionCount.get() + " ]");
    }

    private String getFileName(String url) {
        String suffix = url.substring(url.lastIndexOf("/") + 1);
        if (suffix.contains("?")) {
            suffix = suffix.split("[?]")[0]; // 这个 ? ，不能直接使用，必须转义一下
        }
        // 后缀默认就是 jpeg
        suffix = -1 != suffix.lastIndexOf(".") ? suffix.substring(suffix.lastIndexOf(".")) : ".jpeg";
        return UUID.randomUUID().toString() + suffix;
    }
    public static void setHeaders(HttpGet get) {
        get.setHeader("Accept",				"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
        get.setHeader("Accept-Encoding", "gzip, deflate, br");
        get.setHeader("Cache-Control", "max-age=0");
        get.setHeader("Connection", "keep-alive");
        get.setHeader("Cookie","自己登录的cookie信息");// **自己登录的cookie信息**
        get.setHeader("Host", "image.baidu.com");
        get.setHeader("Upgrade-Insecure-Requests", "1");
        get.setHeader("User-Agent",
                "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36");
    }
}

